package top.wilsonlv.jaguar.cloud.upms.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import top.wilsonlv.jaguar.basecrud.BaseService;
import top.wilsonlv.jaguar.cloud.upms.entity.Device;
import top.wilsonlv.jaguar.cloud.upms.mapper.DeviceMapper;
import top.wilsonlv.jaguar.cloud.upms.sdk.dto.DeviceBindDTO;
import top.wilsonlv.jaguar.cloud.upms.sdk.vo.DeviceVO;
import top.wilsonlv.jaguar.commons.data.encryption.util.EncryptionUtil;
import top.wilsonlv.jaguar.commons.web.exception.impl.CheckedException;

import java.util.Map;

/**
 * <p>
 * 终端设备 服务实现类
 * </p>
 *
 * @author lvws
 * @since 2022-01-13
 */
@Service
public class DeviceService extends BaseService<Device, DeviceMapper> {

    @Lazy
    @Autowired
    private UserDeviceService userDeviceService;


    public Device getByDeviceUid(String deviceUid) {
        return this.unique(Wrappers.lambdaQuery(Device.class)
                .eq(Device::getDeviceUid, deviceUid));
    }

    public DeviceVO getDetail(Long id) {
        Device device = this.getById(id);
        return device.toVo(DeviceVO.class);
    }

    public Page<DeviceVO> queryDevice(Page<Device> page, LambdaQueryWrapper<Device> wrapper) {
        page = this.query(page, wrapper);
        return this.toVoPage(page, DeviceVO.class);
    }

    @Transactional
    public void bindDevice(Long userId, String deviceIp, DeviceBindDTO bindDTO,
                           Long timestamp, String nonce, String sign, Map<String, String[]> params) {
        if (StringUtils.hasText(bindDTO.getDevicePublicKey())) {
            String error = EncryptionUtil.checkRequestBySign(timestamp, nonce, sign, params, bindDTO.getDevicePublicKey());
            if (StringUtils.hasText(error)) {
                throw new CheckedException(error);
            }
        }

        this.bindDevice(userId, deviceIp, bindDTO);
    }

    @Transactional
    public void bindDevice(Long userId, String deviceIp, DeviceBindDTO bindDTO) {
        Device device = bindDTO.toEntity(Device.class);
        device.setDeviceIp(deviceIp);

        Device persistence = this.getByDeviceUid(bindDTO.getDeviceUid());
        if (persistence == null) {
            this.insert(device);
        } else {
            device.setId(persistence.getId());
            this.updateById(device);
        }

        userDeviceService.bindUserDevice(userId, device.getId());
    }


}
